package com.daji.concurrency.multithread_future_callback;

import java.util.concurrent.CompletableFuture;


/*
    CompletableFuture更强大的功能是，多个CompletableFuture可以串行执行，例如，定义两个CompletableFuture，
    第一个CompletableFuture根据证券名称查询证券代码，
    第二个CompletableFuture根据证券代码查询证券价格，这两个CompletableFuture实现串行操作如下：
*/
public class E03_CompletableFuture {

    public static void main(String[] args) throws Exception {
        // 第一个任务:
        CompletableFuture<String> cfQuery = CompletableFuture.supplyAsync(() -> {
            return queryCode("中国石油");
        });
        // cfQuery成功后继续执行下一个任务:
        //上面的执行时supplyAsync，这里执行的是thenApplyAsync。由上面已经执行完的cfQuery调用
        CompletableFuture<Double> cfFetch = cfQuery.thenApplyAsync((code) -> {
            return fetchPrice(code);
        });
        // cfFetch成功后打印结果:
        // thenAccept 负责线程执行完后异步回调。
        cfFetch.thenAccept((result) -> {
            System.out.println("两个子线程已执行完毕，回调函数已执行:");
            System.out.println("price: " + result);
        });
        // 主线程不要立刻结束，否则CompletableFuture默认使用的线程池会立刻关闭:
        System.out.println("主线程会先于回调函数执行。");
        Thread.sleep(20000);
    }

    static String queryCode(String name) {
        try {
            Thread.sleep(100);
            System.out.println("先执行线程queryCode，queryCode的返回值是："+601857);
        } catch (InterruptedException e) {
        }
        return "601857";
    }


    static Double fetchPrice(String code) {
        try {
            System.out.println("然后根据queryCode线程的返回值作为fetchPrice线程的入参。fetchPrice的入参是："+code);
            Thread.sleep(1000);
        } catch (InterruptedException e) {
        }
        return 5 + Math.random() * 20;
    }
}

